#include "linechartwidget.h"
#include <QPainter>
#include <QPainterPath>
ChartWidget::ChartWidget(QWidget *parent)
    :QWidget(parent)
    ,minTime(0)
    ,maxTime(0)
    ,minValue(0.0)
    ,maxValue(100.0)
{
    // 设置颜色
    totalColor = QColor(46, 134, 171); // 蓝
    userColor = QColor(162, 59, 114); // 紫
    systemColor = QColor(241, 143, 1);  // 橙
    gridColor = QColor(200, 200, 200);  // 浅灰
    axisColor = QColor(100, 100, 100); // 深灰
    backgroundColor = QColor(255, 255, 255);  //白

    // 设置背景色
    setAutoFillBackground(true);
    QPalette pal = palette();
    pal.setColor(QPalette::Window, backgroundColor);
    setPalette(pal);

    // 设置最小尺寸
    setMinimumSize(600, 400);
}

void ChartWidget::updateData(const CPUData &data, bool isLocalData) {
    // 添加数据
    dataHistory.append(data);
    dataSourceFlags.append(isLocalData);

    // 限制数据点的数量
    if(dataHistory.size() > MAX_DATA_POINTS) {
        dataHistory.removeFirst();
        dataSourceFlags.removeFirst();
    }
    // 更新坐标轴范围
    if(!dataHistory.isEmpty()) {
        minTime = dataHistory.first().timestamp;
        maxTime = dataHistory.last().timestamp;
        // 确保显示60s数据
        if(maxTime-minTime < 60000) {
            maxTime = minTime + 60000;
        }
        // 触发重绘
        update();
        // // 触发重绘（优化：减少重绘频率）
        // static int updateCounter = 0;
        // updateCounter++;
        // // 每3次数据更新才重绘一次，减少CPU占用
        // if (updateCounter % 3 == 0) {
        //     update();
        // }
    }
}

// 清空图表数据
void ChartWidget::clearData()
{
    dataHistory.clear();
    dataSourceFlags.clear();
    minTime = 0;
    maxTime = 0;
    update();
}

void ChartWidget::paintEvent(QPaintEvent *event)
{
    // 创建画笔
    QPainter painter(this);
    // 设置抗锯齿
    painter.setRenderHint(QPainter::Antialiasing);

    // 计算绘图区域
    int margin = 60;
    int legendHeight = 80;
    // 创建区域
    chartRect = QRect(margin, margin, width() - 2 * margin, height() - 2 * margin - legendHeight);
    legendRect = QRect(margin, height() - margin - legendHeight, width() - 2 * margin, legendHeight);

    // 绘制各个部分
    drawBackground(painter);
    drawGrid(painter);
    drawAxes(painter);
    drawLines(painter);
    drawLegend(painter);
}

void ChartWidget::resizeEvent(QResizeEvent *event)
{
    QWidget::resizeEvent(event);
    update();
}

void ChartWidget::drawBackground(QPainter &painter)
{
    // 绘制图表背景
    painter.fillRect(chartRect, backgroundColor);

    // 绘制边框
    painter.setPen(QPen(axisColor, 2));
    painter.drawRect(chartRect);
}

// 绘制网格
void ChartWidget::drawGrid(QPainter &painter) {
    painter.setPen(QPen(gridColor, 1, Qt::DotLine));

    // 绘制水平网格线
    for(int i = 0; i <= 5; ++i) {
        int y = chartRect.top() + (chartRect.height()*i)/5;
        painter.drawLine(chartRect.left(), y, chartRect.right(), y);
    }
    // 绘制垂直网格线
    for(int i = 0; i <= 6; i++) {
        int x = (chartRect.width()*i)/6 + chartRect.left();
        painter.drawLine(x, chartRect.top(), x, chartRect.bottom());
    }
}

// 绘制网格标签
void ChartWidget::drawAxes(QPainter &painter) {
    painter.setPen(QPen(axisColor, 2));
    painter.setFont(QFont("Arial", 8));

    // 绘制y轴标签
    for(int i = 0; i <= 5; i++) {
        int y = chartRect.top() + (chartRect.height()*i)/5;
        int value = maxValue - (maxValue - minValue)*i/5;
        QString label = QString::number(value, 'f', 0) + "%";
        QRect textrect = QRect(chartRect.left()-50, y-10, 40, 20);
        painter.drawText(textrect, Qt::AlignRight | Qt::AlignVCenter, label);
    }

    // 绘制x轴标签
    if(!dataHistory.isEmpty()) {
        for(int i = 0; i <= 6; i++) {
            int x = (chartRect.width()*i)/6 + chartRect.left();
            qint64 time = minTime + (maxTime - minTime)* i/6;
            QString label = formatTime(time);

            QRect textrect = QRect(x-30, chartRect.bottom()+5, 60, 20);
            painter.drawText(textrect, Qt::AlignCenter, label);
        }
    }
}

// 绘制图例
void ChartWidget::drawLegend(QPainter &painter) {
    painter.setFont(QFont("Arial", 10, QFont::Bold));

    // 初始化位置参数
    int x = legendRect.left();
    int y = legendRect.top() + 20;
    int lineheight = 25;

    // cpu总使用率
    painter.setPen(QPen(totalColor, 3));
    painter.drawLine(x, y, x + 20, y);
    painter.setPen(QPen(axisColor));
    painter.drawText(x + 30, y + 5, "总CPU使用率");

    // 用户态使用率
    y += lineheight;
    painter.setPen(QPen(userColor, 3));
    painter.drawLine(x, y, x+20, y);
    painter.setPen(QPen(axisColor));
    painter.drawText(x + 30, y + 5, "用户态CPU使用率");

    // 内核态使用率
    y += lineheight;
    painter.setPen(QPen(systemColor, 3));
    painter.drawLine(x, y, x+20, y);
    painter.setPen(QPen(axisColor));
    painter.drawText(x + 30, y + 5, "内核态CPU使用率");
}

// 绘制折线
void ChartWidget::drawLines(QPainter &painter) {
    if(dataHistory.size() < 2)  return;

    // 绘制本地数据（实线）
    QPainterPath localTotalPath, localUserPath, localSystemPath;
    // 绘制远程数据（虚线）
    QPainterPath remoteTotalPath, remoteUserPath, remoteSystemPath;

    bool firstLocal = true, firstRemote = true;

    // 遍历所有数据点
    for (int i = 0; i < dataHistory.size(); ++i) {
        const CPUData &data = dataHistory[i];
        bool isLocal = dataSourceFlags[i];

        if (isLocal) {
            // 本地数据 - 实线
            QPoint totalPoint = mapToWidget(data.timestamp, data.total);
            QPoint userPoint = mapToWidget(data.timestamp, data.user);
            QPoint systemPoint = mapToWidget(data.timestamp, data.system);

            if (firstLocal) {
                localTotalPath.moveTo(totalPoint);
                localUserPath.moveTo(userPoint);
                localSystemPath.moveTo(systemPoint);
                firstLocal = false;
            } else {
                localTotalPath.lineTo(totalPoint);
                localUserPath.lineTo(userPoint);
                localSystemPath.lineTo(systemPoint);
            }
        } else {
            // 远程数据 - 虚线
            QPoint totalPoint = mapToWidget(data.timestamp, data.total);
            QPoint userPoint = mapToWidget(data.timestamp, data.user);
            QPoint systemPoint = mapToWidget(data.timestamp, data.system);

            if (firstRemote) {
                remoteTotalPath.moveTo(totalPoint);
                remoteUserPath.moveTo(userPoint);
                remoteSystemPath.moveTo(systemPoint);
                firstRemote = false;
            } else {
                remoteTotalPath.lineTo(totalPoint);
                remoteUserPath.lineTo(userPoint);
                remoteSystemPath.lineTo(systemPoint);
            }
        }
    }

    // 绘制本地数据（实线）
    painter.setPen(QPen(totalColor, 2, Qt::SolidLine));
    painter.drawPath(localTotalPath);

    painter.setPen(QPen(userColor, 2, Qt::SolidLine));
    painter.drawPath(localUserPath);

    painter.setPen(QPen(systemColor, 2, Qt::SolidLine));
    painter.drawPath(localSystemPath);

    // 绘制远程数据（虚线）
    painter.setPen(QPen(totalColor, 2, Qt::DashLine));
    painter.drawPath(remoteTotalPath);

    painter.setPen(QPen(userColor, 2, Qt::DashLine));
    painter.drawPath(remoteUserPath);

    painter.setPen(QPen(systemColor, 2, Qt::DashLine));
    painter.drawPath(remoteSystemPath);
}

// 坐标映射，返回绝对位置
QPoint ChartWidget::mapToWidget(qint64 timestamp, double value)
{
    //如果是一个点就不画
    if (maxTime == minTime) return QPoint(0, 0);
    // 相对位置，投影
    int x = chartRect.left() + (timestamp - minTime) * chartRect.width() / (maxTime - minTime);
    int y = chartRect.bottom() - (value - minValue) * chartRect.height() / (maxValue - minValue);
    //返回映射后点的绝对位置
    return QPoint(x, y);
}

// 格式化时间
QString ChartWidget::formatTime(qint64 timestamp)
{
    QDateTime dateTime = QDateTime::fromMSecsSinceEpoch(timestamp);
    return dateTime.toString("hh:mm:ss");
}
